﻿#region zh-CHS 2006 - 2010 DemoSoft 团队 | en 2006-2010 DemoSoft Team

//     NOTES
// ---------------
//
// This file is a part of the MMOSE(Massively Multiplayer Online Server Engine) for .NET.
//
//                              2006-2010 DemoSoft Team
//
//
// First Version : by H.Q.Cai - mailto:caihuanqing@hotmail.com

/***************************************************************************
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published
 *   by the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 ***************************************************************************/

#region zh-CHS 包含名字空间 | en Include namespace
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Demo.Mmose.Core.Util;
using Demo.Mmose.Core.Collections;
using Demo.Mmose.Core.Common.SafeCollections;
#endregion

namespace Demo.Mmose.Core.Entity.Suit.Spell
{

    /// <summary>
    /// 
    /// </summary>
    public class AuraEvenHandler
    {
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private SafeDictionary<long, SafeDictionary<Aura, object>> m_HighestAuraEvens = new SafeDictionary<long, SafeDictionary<Aura, object>>( 1024 );
        /// <summary>
        /// 
        /// </summary>
        private SafeDictionary<long, SafeDictionary<Aura, object>> m_NormalAuraEvens = new SafeDictionary<long, SafeDictionary<Aura, object>>( 1024 );
        /// <summary>
        /// 
        /// </summary>
        private SafeDictionary<long, SafeDictionary<Aura, object>> m_LowestAuraEvens = new SafeDictionary<long, SafeDictionary<Aura, object>>( 1024 );
        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <param name="dddd"></param>
        public void LogIn<ObjectT, AuraT>( long auraEvenId, AuraEvenPriority auraEvenPriority, AuraT aura, AuraEvenCallback<ObjectT, AuraT> callBack ) where AuraT : Aura
        {
            SafeDictionary<long, SafeDictionary<Aura, object>> auraEvenDictionary = null;
            switch ( auraEvenPriority )
            {
                case AuraEvenPriority.Normal:

                    auraEvenDictionary = m_NormalAuraEvens;
                    break;
                case AuraEvenPriority.Highest:

                    auraEvenDictionary = m_HighestAuraEvens;
                    break;
                case AuraEvenPriority.Lowest:

                    auraEvenDictionary = m_LowestAuraEvens;
                    break;
                default:

                    break;
            }

            if ( auraEvenDictionary == null )
                return;

            SafeDictionary<Aura, object> auraDictionary = null;
            SafeDictionary<Aura, object> addAuraDictionary = null;
            do
            {
                if ( auraEvenDictionary.TryGetValue( auraEvenId, out auraDictionary ) == false )
                {
                    if ( addAuraDictionary == null )
                        addAuraDictionary = new SafeDictionary<Aura, object>( 1024 );

                    if ( auraEvenDictionary.TryAdd( auraEvenId, addAuraDictionary ) == true )
                    {
                        auraDictionary = addAuraDictionary;
                        break;
                    }
                }
            } while ( auraDictionary == null );

            AuraEven<ObjectT, AuraT> auraEven = new AuraEven<ObjectT, AuraT>() { Aura = aura, Callback = callBack };

            if ( auraDictionary != null )
                auraDictionary.AddOrReplace( aura, auraEven );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="ObjectT"></typeparam>
        /// <typeparam name="AuraT"></typeparam>
        /// <param name="auraEvenId"></param>
        /// <param name="auraObject"></param>
        /// <returns>回调了几次</returns>
        public int Callback<ObjectT, AuraT>( long auraEvenId, ObjectT auraObject ) where AuraT : Aura
        {
            int iCallbackCount = 0;

            // Callback 最高优先级
            SafeDictionary<Aura, object> auraDictionary = null;
            if ( m_HighestAuraEvens.TryGetValue( auraEvenId, out auraDictionary ) == true )
            {
                if ( auraDictionary != null )
                {
                    foreach ( var auraEvenObject in auraDictionary.ToArray() )
                    {
                        AuraEven<ObjectT, AuraT> auraEven = auraEvenObject.Value as AuraEven<ObjectT, AuraT>;
                        if ( auraEven != null )
                        {
                            auraEven.Object = auraObject;
                            auraEven.Callback( auraEven );

                            iCallbackCount++;
                        }
                    }
                }
            }

            // Callback 普通优先级
            auraDictionary = null;
            if ( m_NormalAuraEvens.TryGetValue( auraEvenId, out auraDictionary ) == true )
            {
                if ( auraDictionary != null )
                {
                    foreach ( var auraEvenObject in auraDictionary.ToArray() )
                    {
                        AuraEven<ObjectT, AuraT> auraEven = auraEvenObject.Value as AuraEven<ObjectT, AuraT>;
                        if ( auraEven != null )
                        {
                            auraEven.Object = auraObject;
                            auraEven.Callback( auraEven );

                            iCallbackCount++;
                        }
                    }
                }
            }

            // Callback 最低优先级
            auraDictionary = null;
            if ( m_LowestAuraEvens.TryGetValue( auraEvenId, out auraDictionary ) == false )
            {
                if ( auraDictionary != null )
                {
                    foreach ( var auraEvenObject in auraDictionary.ToArray() )
                    {
                        AuraEven<ObjectT, AuraT> auraEven = auraEvenObject.Value as AuraEven<ObjectT, AuraT>;
                        if ( auraEven != null )
                        {
                            auraEven.Object = auraObject;
                            auraEven.Callback( auraEven );

                            iCallbackCount++;
                        }
                    }
                }
            }

            return iCallbackCount;
        }

        /// <summary>
        /// 
        /// </summary>
        public void AsyncCallback<ObjectT, AuraT>( long auraEvenId, ObjectT auraObject ) where AuraT : Aura
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 
        /// </summary>
        public void LogOut<AuraT>( long auraEvenId, AuraT aura ) where AuraT : Aura
        {
            SafeDictionary<Aura, object> auraDictionary = null;
            if ( m_HighestAuraEvens.TryGetValue( auraEvenId, out auraDictionary ) == true )
            {
                if ( auraDictionary != null )
                    auraDictionary.Remove( aura );
            }

            auraDictionary = null;
            if ( m_NormalAuraEvens.TryGetValue( auraEvenId, out auraDictionary ) == true )
            {
                if ( auraDictionary != null )
                    auraDictionary.Remove( aura );
            }

            auraDictionary = null;
            if ( m_LowestAuraEvens.TryGetValue( auraEvenId, out auraDictionary ) == true )
            {
                if ( auraDictionary != null )
                    auraDictionary.Remove( aura );
            }
        }

    }

}
#endregion
